package control.manager
{
	import control.util.bfs.BFS;
	
	import data.ExitsData;
	import data.GameConst;
	import data.LevelVO;
	import data.MapData;
	import data.MonsterData;
	import data.PlayerData;
	import data.TaskVO;
	import data.UserTaskVO;
	
	import flash.display.Sprite;
	import flash.geom.Point;
	
	import view.layer.GameLayer;
	import view.layer.RoleLayer;
	import view.role.MapMonster;
	import view.role.MapNPC;
	import view.role.MapObject;
	import view.role.MapPlayer;
	import view.ui.UIBottom;
	import view.ui.UIMain;
	import view.ui.UIRoleHead;

	/**
	 * 角色管理器 
	 * @author leo
	 * 
	 */	
	public class RoleManager
	{
		private static var _instance :RoleManager = null;
		/**
		 * 玩家人物数据 
		 */		
		public var playerData :PlayerData;
		/**
		 * 当前地图上的角色列表 
		 */		
		public var roleList :Array;
		/**
		 * 游戏中所有NPC的ID数组 
		 */		
		public var npcIDList :Array;
		/**
		 * 游戏中所有怪物的ID数组 
		 */		
		public var monsterIDList :Array;
		/**
		 * 需要切换地图查找的NPC ID
		 */		
		public var needWalkPoint :Array;
		
		public function RoleManager(prv :PrivateClass)
		{
			this.roleList = [];
			this.npcIDList = [];
			monsterIDList = [];
		}
		
		public static function get instance():RoleManager
		{
			if(_instance == null)
			{
				_instance = new RoleManager(new PrivateClass());
			}
			return _instance;
		}
		
		public function get player():MapPlayer
		{
			var gameLayer :GameLayer = LayerManager.instance.getLayer(GameLayer.NAME) as GameLayer;
			if(gameLayer)
			{
				var player :MapPlayer = gameLayer.player;
				
				return player;
			}
			
			return null;
		}
		/**
		 * 设置小头像的名字/等级等 
		 * 
		 */		
		public function setRoleUIDisplay():void
		{
			var mainUI :UIMain  = LayerManager.instance.getLayer(UIMain.NAME) as UIMain;
			if(!mainUI)
			{
				return;
			}
			var uiRole :UIRoleHead = mainUI.roleHeadUI;
			uiRole.txtName.text = this.playerData.roleName;
			uiRole.txtLevel.text = this.playerData.playerLevel.toString();
			
			var bottomUI :UIBottom = mainUI.bottomUI;
			bottomUI.expBar.width = 1;
			var curExp :int = playerData.playerExp;
			var levleList :Array = DataManager.I.levelList;
			var nextExp :int = 0;
			nextExp = (levleList[playerData.playerLevel] as LevelVO).exp;
			bottomUI.txtExp.text = curExp + "/" + nextExp;
			
			var percent :Number = curExp/nextExp;
			var w :int = bottomUI.expBarCopy.width * percent;
			bottomUI.expBar.width = w;
		}
		
		/**
		 * 查找地图上某一类型的怪物 
		 * @param monsterID
		 * @return 
		 * 
		 */		
		public function findMonsterByID(monsterID :String):MapMonster
		{
			for each(var mapObj :MapObject in this.roleList)
			{
				if(mapObj is MapMonster)
				{
					var tempMonster :MapMonster = mapObj as MapMonster;
					if(tempMonster.monsterData.monsterID == monsterID)
					{
						return tempMonster; 
					}
				}
			}
			return null;
		}
		/**
		 * 检查该NPC是否需要切换地图才可以找到 
		 * @param npcID
		 * 
		 */		
		public function isNeedChangeMapByNPC(npcID :String):void
		{
			if(this.npcIDList.length > 0)
			{
				if(this.npcIDList.indexOf(npcID) == -1)
				{
					trace("游戏中没有设定该NPC" + npcID);
					return;
				}
			}
			
			if(npcID.indexOf(playerData.curMapID.toString()) == -1)
			{
				trace(npcID + "该NPC不在这个地图上，地图ID ： " + playerData.curMapID);
				
				trace("需要切换地图啊，哥！");
				
				var start :int = npcID.lastIndexOf("c") + 1;
				var end :int = npcID.lastIndexOf("_");
				var mapID :String = npcID.substring(start,end);
				//需要切换地图
				this.needWalkPoint = BFS.I.findPath(playerData.curMapID,int(mapID));
				this.needWalkPoint.push(npcID);
				
				var obj :Object = this.needWalkPoint.shift();
				if(obj is ExitsData)
				{
					var ed :ExitsData = obj as ExitsData;
					player.findPath(player.position,ed.exitsPosition);
				}else
				{
					trace("不用切换地图！你Y");
				}
				
				return;
			}
			
		}
		
		public function isNeedChangeMapByMonster(monsterID :String):void
		{
			if(this.monsterIDList.length > 0)
			{
				if(this.monsterIDList.indexOf(monsterID) == -1)
				{
					trace("游戏中没有设定该怪物" + monsterID);
					return;
				}
			}
			
			if(monsterID.indexOf(playerData.curMapID.toString()) == -1)
			{
				trace(monsterID + "该怪不在这个地图上，地图ID ： " + playerData.curMapID);
				
				trace("需要切换地图啊，哥！");
				
				var start :int = monsterID.lastIndexOf("c") + 1;
				var end :int = monsterID.lastIndexOf("_");
				var mapID :String = monsterID.substring(start,end);
				//需要切换地图
				this.needWalkPoint = BFS.I.findPath(playerData.curMapID,int(mapID));
				this.needWalkPoint.push(monsterID);
				
				var obj :Object = this.needWalkPoint.shift();
				if(obj is ExitsData)
				{
					var ed :ExitsData = obj as ExitsData;
					player.findPath(player.position,ed.exitsPosition);
				}else
				{
					trace("不用切换地图！你Y");
				}
				
				return;
			}
		}
		/**
		 * 通过NPC ID 查找地图上的NPC 
		 * @param npcID
		 * @return 
		 * 
		 */		
		public function findNPCByID(npcID :String):MapNPC
		{
			
//			if(needChangeMap)
//			{
//				return null;
//			}
			
			for each(var mapObj :MapObject in this.roleList)
			{
				if(mapObj is MapNPC)
				{
					var tempNPC :MapNPC = mapObj as MapNPC;
					if(tempNPC.npcData.npcID == npcID)
					{
						return tempNPC; 
					}
				}
			}
			
			return null;
		}
		
		/**
		 * 寻找第一次进入游戏需要的任务NPC 
		 * @return 
		 * 
		 */		
		public function findFirstTaskNPC():MapNPC
		{
			var taskList :Array = TaskManager.instance.findCanAcceptTaskList();
			
			if(!taskList || taskList.length == 0) return null;
			var taskVO :TaskVO = taskList[0];
			var npc :MapNPC;
			
			if(taskVO)
			{
				npc = findNPCByID(taskVO.sendNPCID);
				if(npc)
				{
					npc.npcData.canDoList.push(taskVO);
					npc.setTaskStatus(GameConst.HAVE_TASK);
				}
			}
			return npc;
		}
		/**
		 * 根据玩家数据改变NPC的显示状态 
		 * @param playerData
		 * 
		 */		
		public function changeNpcStatus(playerData :PlayerData = null):void
		{
			if(!playerData)
			{
				playerData = this.playerData;
			}
			
			if(!playerData)
			{
				return;
			}
			var userTaskVO :UserTaskVO;
			var sendNPC :MapNPC;
			var completeNPC :MapNPC;
			for each(userTaskVO in playerData.taskingList)
			{
				if(userTaskVO.isTasking)  //进行中
				{
					sendNPC = findNPCByID(userTaskVO.sendID);
					if(sendNPC)
					{
						sendNPC.clearTaskStatus();
					}
					completeNPC = findNPCByID(userTaskVO.completeID);
					if(completeNPC)
					{
						if(userTaskVO.taskSort == TaskVO.TALK_SORT)
						{
							completeNPC.setTaskStatus(GameConst.CAN_COMPLETE);
							userTaskVO.canComplete = true;
						}
						else
						{
							completeNPC.setTaskStatus(GameConst.TASKING);
						}
					}
				}else if(userTaskVO.isComplete) //已经完成
				{
					sendNPC = findNPCByID(userTaskVO.sendID);
					if(sendNPC)
					{
						sendNPC.clearTaskStatus();
					}
					completeNPC = findNPCByID(userTaskVO.completeID);
					if(completeNPC)
					{
						completeNPC.clearTaskStatus();
					}
				}else if(userTaskVO.canComplete) //可以完成
				{
					sendNPC = findNPCByID(userTaskVO.sendID);
					if(sendNPC)
					{
						sendNPC.clearTaskStatus();
					}
					completeNPC = findNPCByID(userTaskVO.completeID);
					if(completeNPC)
					{
						completeNPC.setTaskStatus(GameConst.CAN_COMPLETE);
					}
					
				}
			}
		}
		/**
		 * 删除地图上的角色 
		 * @param item
		 * 
		 */		
		public function removeRole(item :MapObject):void
		{
			var roleLayer :RoleLayer = LayerManager.instance.getLayer(RoleLayer.NAME) as RoleLayer;
			if(!roleLayer) return;
			roleLayer.removeChild(item);
			for(var i :int = this.roleList.length - 1; i >= 0; i--)
			{
				var tempItem :MapObject = this.roleList[i] as MapObject;
				if(item.uid == tempItem.uid)
				{
					this.roleList.splice(i,1);
					item = null;
					break;
				}
			}
		}
		/**
		 * 增加角色 
		 * @param item
		 * 
		 */		
		public function addRole(item :MapObject):void
		{
			var roleLayer :RoleLayer = LayerManager.instance.getLayer(RoleLayer.NAME) as RoleLayer;
			if(!roleLayer) return;
			roleLayer.addChild(item);
			this.roleList.push(item);
		}
		
		/**
		 * Y轴排序 
		 * @param container
		 * @param arr
		 * 
		 */		
		public function sortY(container:Sprite, arr:Array):void  
		{  
			arr.sortOn("y", Array.NUMERIC);  
			for (var i:int = arr.length - 1; i >= 0 ; i--)  
			{  
				var tempDisplayObject :MapObject = arr[i];  
				container.setChildIndex(tempDisplayObject,i);  
			}  
		}
		
		/**
		 * 获取一个范围内的点 
		 * @param monsterData
		 * @return 
		 * 
		 */		
		public function getAroundPoint(monsterData :MonsterData):Array
		{
			var result :Array = [];
			var curMapData :MapData = MapManager.instance.curMapData;
//			var mapWalkAry :Array = curMapData.mapWalkAry;
			//以这两点为一个区域，区域内随机点出怪
			var start :Point = monsterData.monsterAppearArea[0];
			var end :Point = monsterData.monsterAppearArea[1];
			
			var pAry :Array = [];
			var p :Point;
			for(var i :int = start.x; i < end.x; i++)
			{
				for(var j :int = start.y; j < end.y; j++)
				{
					p = new Point(i,j);
					pAry.push(p);
				}
			}
			if(pAry.length > 0)
			{
				if(pAry.length < monsterData.monsterNumber)
				{
					result = pAry;
				}else
				{
					while(result.length < monsterData.monsterNumber)
					{
						var index :int = (pAry.length - 1) * Math.random();
						result.push((pAry.splice(index,1) as Array).shift() as Point);
					}
				}
			}
			return result;
		}

	}
}

class PrivateClass{}